home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
CD ROM Paradise Collection 4
/
CD ROM Paradise Collection 4 1995 Nov.iso
/
program
/
vgl20.zip
/
VGLGIF.C
< prev
next >
Wrap
C/C++ Source or Header
|
1993-05-14
|
5KB
|
210 lines
/*****************************************************************************
VGLGIF.C
vglGif( char* file, char far* buffer, char far* palette,
int* width, int* height );
Routine to load a 256 color .GIF file into a memory buffer. *Only* 256
color images are supported here! Sorry, no routines to SAVE .GIFs...
Memory required is allocated on the fly and no checks are in place. If you
don't have enough memory it will likely crash. It's easy to add the checks
yourself, just put one after each call to malloc(). If you supply a pointer
to a palette, it will be filled in. If you supply a pointer to a width
and/or height variable, it will be filled in as well.
Mark Morley
morley@camosun.bc.ca
*****************************************************************************/
#include <stdio.h>
#define MAX_CODES 4096
static FILE* fp;
static int curr_size;
static int clear;
static int ending;
static int newcodes;
static int top_slot;
static int slot;
static int navail_bytes = 0;
static int nbits_left = 0;
static unsigned char b1;
static unsigned char byte_buff[257];
static unsigned char* pbytes;
static unsigned char* stack;
static unsigned char* suffix;
static unsigned int* prefix;
static unsigned long code_mask[13] =
{
0L,
0x0001L, 0x0003L,
0x0007L, 0x000FL,
0x001FL, 0x003FL,
0x007FL, 0x00FFL,
0x01FFL, 0x03FFL,
0x07FFL, 0x0FFFL
};
static int pascal
get_next_code()
{
register int i;
static unsigned long ret;
if( ! nbits_left )
{
if( navail_bytes <= 0 )
{
pbytes = byte_buff;
navail_bytes = getc( fp );
if( navail_bytes )
for( i = 0; i < navail_bytes; ++i )
*(byte_buff + i) = getc( fp );
}
b1 = *pbytes++;
nbits_left = 8;
--navail_bytes;
}
ret = b1 >> (8 - nbits_left);
while( curr_size > nbits_left )
{
if( navail_bytes <= 0 )
{
pbytes = byte_buff;
navail_bytes = getc( fp );
if( navail_bytes )
for( i = 0; i < navail_bytes; ++i )
*(byte_buff + i) = getc( fp );
}
b1 = *pbytes++;
ret |= b1 << nbits_left;
nbits_left += 8;
--navail_bytes;
}
nbits_left -= curr_size;
return( (int) (ret & *(code_mask + curr_size)) );
}
vglGif( char* file, char far* buffer, char far* pal, int* width, int* height )
{
unsigned char* sp;
int code, fc, oc;
int i;
unsigned char size;
int c;
unsigned char buf[1028];
unsigned char red;
unsigned char grn;
unsigned char blu;
fp = fopen( file, "rb" );
if( !fp )
return( 0 );
fread( buf, 1, 6, fp );
if( strncmp( buf, "GIF", 3 ) )
{
fclose( fp );
return( 0 );
}
fread( buf, 1, 7, fp );
for( i = 0; i < 768; )
{
red = getc( fp );
grn = getc( fp );
blu = getc( fp );
if( pal )
{
pal[i++] = red >> 2;
pal[i++] = grn >> 2;
pal[i++] = blu >> 2;
}
else
i += 3;
}
fread( buf, 1, 5, fp );
i = getw( fp );
if( width )
*width = i;
i = getw( fp );
if( height )
*height = i;
if( !buffer )
return( 1 );
fread( buf, 1, 1, fp );
size = getc( fp );
if( size < 2 || 9 < size )
{
fclose( fp );
return( 0 );
}
stack = (unsigned char*) malloc( MAX_CODES + 1 );
suffix = (unsigned char*) malloc( MAX_CODES + 1 );
prefix = (unsigned int*) malloc( sizeof(int) * (MAX_CODES + 1) );
curr_size = size + 1;
top_slot = 1 << curr_size;
clear = 1 << size;
ending = clear + 1;
slot = newcodes = ending + 1;
navail_bytes = nbits_left = 0;
oc = fc = 0;
sp = stack;
while( (c = get_next_code()) != ending )
{
if( c == clear )
{
curr_size = size + 1;
slot = newcodes;
top_slot = 1 << curr_size;
while( (c = get_next_code()) == clear );
if( c == ending )
break;
if( c >= slot )
c = 0;
oc = fc = c;
*buffer++ = c;
}
else
{
code = c;
if( code >= slot )
{
code = oc;
*sp++ = fc;
}
while( code >= newcodes )
{
*sp++ = *(suffix + code);
code = *(prefix + code);
}
*sp++ = code;
if( slot < top_slot )
{
*(suffix + slot) = fc = code;
*(prefix + slot++) = oc;
oc = c;
}
if( slot >= top_slot && curr_size < 12 )
{
top_slot <<= 1;
++curr_size;
}
while( sp > stack )
{
--sp;
*buffer++ = *sp;
}
}
}
free( stack );
free( suffix );
free( prefix );
fclose( fp );
return( 1 );
}